---
title: "Accordion"
description: "Accordion display a list of high-level options that can expand/collapse to reveal more information."
---

import {accordionContent} from "@/content/components/accordion";

# Accordion

Accordion display a list of high-level options that can expand/collapse to reveal more information.

<ComponentLinks component="accordion" />

---

<CarbonAd/>

## Installation

<PackageManagers
  showGlobalInstallWarning
  commands={{
    cli: "npx heroui-cli@latest add accordion",
    npm: "npm install @heroui/accordion",
    yarn: "yarn add @heroui/accordion",
    pnpm: "pnpm add @heroui/accordion",
    bun: "bun add @heroui/accordion"
  }}
/>

## Import

HeroUI exports 2 accordion-related components:

- **Accordion**: The main component to display a list of accordion items.
- **AccordionItem**: The item component to display a single accordion item.

<ImportTabs
  commands={{
    main: 'import {Accordion, AccordionItem} from "@heroui/react";',
    individual: 'import {Accordion, AccordionItem} from "@heroui/accordion";',
  }}
/>

## Usage

<CodeDemo title="Usage" files={accordionContent.usage} />

### With Subtitle

<CodeDemo title="With subtitle" files={accordionContent.subtitle} />

### Expand multiple items

If you set `selectionMode` to `multiple`, then the `Accordion` will allow multiple items to be expanded at the same time.

<CodeDemo title="Expand multiple items" files={accordionContent.multiple} />

### Compact

If you set `isCompact` to `true`, the `Accordion` will be displayed in a compact style.

<CodeDemo title="Compact" files={accordionContent.compact} />

### Variants

Accordion has 4 variants: `light`, `shadow`, `bordered` and `splitted`.

#### Light variant

<CodeDemo title="Light variant" files={accordionContent.lightVariant} />

#### Shadow variant

<CodeDemo title="Shadow variant" files={accordionContent.shadowVariant} />

#### Bordered variant

<CodeDemo title="Bordered variant" files={accordionContent.borderedVariant} />

#### Splitted variant

<CodeDemo title="Splitted variant" files={accordionContent.splittedVariant} />

### Default expanded keys

If you want to expand some items by default, you can set the `defaultExpandedKeys` property to an array of keys.

<CodeDemo title="Default expanded keys" files={accordionContent.defaultExpandedKeys} />

### Disabled keys

If you want to disable some items, you can set the `disabledKeys` property to an array of keys.

<CodeDemo title="Disabled keys" files={accordionContent.disabledKeys} />

### Start content

If you want to display some content before the accordion items, you can set the `startContent` property.

<CodeDemo title="Start content" files={accordionContent.startContent} />

### Custom Indicator

Accordion items have a property called `indicator`. You can use it to customize the open/close indicator.

<CodeDemo title="Custom Open/Close Indicator" files={accordionContent.indicator} />

The indicator can be also a `function`, which receives the `isOpen`, `isDisabled` and the default `indicator` as parameters.

<CodeDemo
  title="Custom Open/Close Indicator Function"
  highlightedLines="15"
  files={accordionContent.indicatorFunction}
/>

### Custom Motion

Accordion offers a `motionProps` property to customize the `enter` / `exit` animation.

<CodeDemo title="Custom Motion" files={accordionContent.customMotion} />

> Learn more about Framer motion variants [here](https://www.framer.com/motion/animation/#variants).

### Controlled

Accordion is a controlled component, which means you need to control the `selectedKeys` property by yourself.

<CodeDemo title="Controlled" files={accordionContent.controlled} />

## Accordion Item Slots

- **base**: The accordion item wrapper.
- **heading**: The accordion item heading. It contains the `indicator` and the `title`.
- **trigger**: The button that open/close the accordion item.
- **titleWrapper**: The wrapper of the `title` and `subtitle`.
- **title**: The accordion item title.
- **subtitle**: The accordion item subtitle.
- **startContent**: The content before the accordion item.
- **indicator**: The element that indicates the open/close state of the accordion item.
- **content**: The accordion item content.

### Custom Accordion Styles

You can customize the accordion and accordion items styles by using any of the following properties:

- `className`: The class name of the accordion. Modify the accordion wrapper styles.(Accordion)
- `itemClasses`: The class names of the accordion items. Modify all accordion items styles at once. (Accordion)
- `classNames`: The class names of the accordion items. Modify each accordion item styles separately. (AccordionItem)

Here's an example of how to customize the accordion styles:

<CodeDemo title="Custom Accordion Styles" files={accordionContent.customStyles} />

<Spacer y={4} />

## Data Attributes

`AccordionItem` has the following attributes on the `base` element:

- **data-open**:
  Whether the accordion item is open.
- **data-disabled**:
  When the accordion item is disabled.
- **data-hover**:
  When the accordion item is being hovered. Based on [useHover](https://react-spectrum.adobe.com/react-aria/useHover.html).
- **data-focus**:
  When the accordion item is being focused. Based on [useFocusRing](https://react-spectrum.adobe.com/react-aria/useFocusRing.html).
- **data-focus-visible**:
  When the accordion item is being focused with the keyboard. Based on [useFocusRing](https://react-spectrum.adobe.com/react-aria/useFocusRing.html).
- **data-disabled**:
  When the accordion item is disabled. Based on `isDisabled` prop.
- **data-pressed**:
  When the accordion item is pressed. Based on [usePress](https://react-spectrum.adobe.com/react-aria/usePress.html).

<Spacer y={4} />

## Accessibility

- Keyboard event support for <Kbd>Space</Kbd>, <Kbd>Enter</Kbd>, <Kbd>Arrow Up</Kbd>, <Kbd>Arrow Down</Kbd> and <Kbd>Home</Kbd> / <Kbd>End</Kbd> keys.
- Keyboard focus management and cross browser normalization.
- `aria-expanded` attribute for the accordion item.
- `aria-disabled` attribute for the accordion item.
- `aria-controls` attribute for the accordion item.

<Spacer y={4} />

## API

### Accordion Props

<APITable 
  data={[
    {
      attribute: "children",
      type: "ReactNode | ReactNode[]",
      description: "The contents of the collection. Usually the array of AccordionItem",
      default: "-"
    },
    {
      attribute: "variant",
      type: "light | shadow | bordered | splitted",
      description: "The accordion appearance style.",
      default: "light"
    },
    {
      attribute: "selectionMode", 
      type: "none | single | multiple",
      description: "The type of selection that is allowed in the collection.",
      default: "-"
    },
    {
      attribute: "selectionBehavior",
      type: "toggle | replace",
      description: "The accordion selection behavior.",
      default: "toggle"
    },
    {
      attribute: "isCompact",
      type: "boolean",
      description: "Whether all Accordion items should be smaller.",
      default: "false"
    },
    {
      attribute: "isDisabled",
      type: "boolean", 
      description: "Whether the Accordion items are disabled.",
      default: "false"
    },
    {
      attribute: "showDivider",
      type: "boolean",
      description: "Whether to display a divider at the bottom of the each accordion item.",
      default: "true"
    },
    {
      attribute: "dividerProps",
      type: "DividerProps",
      description: "The divider component props.",
      default: "-"
    },
    {
      attribute: "hideIndicator",
      type: "boolean",
      description: "Whether the Accordion items indicator is hidden.",
      default: "false"
    },
    {
      attribute: "disableAnimation",
      type: "boolean",
      description: "Whether the Accordion items open/close animation is disabled.",
      default: "false"
    },
    {
      attribute: "disableIndicatorAnimation",
      type: "boolean",
      description: "Whether the Accordion items indicator animation is disabled.",
      default: "false"
    },
    {
      attribute: "disallowEmptySelection",
      type: "boolean",
      description: "Whether the collection allows empty selection.",
      default: "false"
    },
    {
      attribute: "keepContentMounted",
      type: "boolean",
      description: "Whether the Accordion items content should be always mounted.",
      default: "false"
    },
    {
      attribute: "fullWidth",
      type: "boolean",
      description: "Whether the accordion should take up the full width of its parent container.",
      default: "true"
    },
    {
      attribute: "motionProps",
      type: "MotionProps",
      description: "The motion properties of the Accordion.",
      default: "-"
    },
    {
      attribute: "disabledKeys",
      type: "React.Key[]",
      description: "The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.",
      default: "-"
    },
    {
      attribute: "itemClasses",
      type: "AccordionItemClassnames",
      description: "The accordion items classNames.",
      default: "-"
    },
    {
      attribute: "selectedKeys",
      type: "all | React.Key[]",
      description: "The currently selected keys in the collection (controlled).",
      default: "-"
    },
    {
      attribute: "defaultSelectedKeys",
      type: "all | React.Key[]",
      description: "The initial selected keys in the collection (uncontrolled).",
      default: "-"
    }
  ]}
/>

### Accordion Events

<APITable
  data={[
    {
      attribute: "onSelectionChange",
      type: "(keys: \"all\" | Set<React.Key>) => any",
      description: "Handler that is called when the selection changes.",
      default: "-"
    }
  ]}
/>

### Accordion Item Props

<APITable
  data={[
    {
      attribute: "children",
      type: "ReactNode",
      description: "The content of the component.",
      default: "-"
    },
    {
      attribute: "title",
      type: "ReactNode",
      description: "The accordion item title.",
      default: "-"
    },
    {
      attribute: "subtitle",
      type: "ReactNode",
      description: "The accordion item subtitle.",
      default: "-"
    },
    {
      attribute: "indicator",
      type: "IndicatorProps",
      description: "The accordion item expanded indicator, usually an arrow icon.",
      default: "-"
    },
    {
      attribute: "startContent",
      type: "ReactNode",
      description: "The accordion item start content, usually an icon or avatar.",
      default: "-"
    },
    {
      attribute: "motionProps",
      type: "MotionProps",
      description: "The props to modify the framer motion animation. Use the variants API to create your own animation.",
      default: "-"
    },
    {
      attribute: "isCompact",
      type: "boolean",
      description: "Whether the AccordionItem is compact.",
      default: "false"
    },
    {
      attribute: "isDisabled",
      type: "boolean",
      description: "The current disabled status.",
      default: "false"
    },
    {
      attribute: "keepContentMounted",
      type: "boolean",
      description: "Whether the AccordionItem content is kept mounted when closed.",
      default: "false"
    },
    {
      attribute: "hideIndicator",
      type: "boolean",
      description: "Whether the AccordionItem indicator is hidden.",
      default: "false"
    },
    {
      attribute: "disableAnimation",
      type: "boolean",
      description: "Whether the AccordionItem animation is disabled.",
      default: "false"
    },
    {
      attribute: "disableIndicatorAnimation",
      type: "boolean",
      description: "Whether the AccordionItem indicator animation is disabled.",
      default: "false"
    },
    {
      attribute: "HeadingComponent",
      type: "React.ElementType",
      description: "Customizable heading tag for Web accessibility. Use headings to describe content and use them consistently and semantically.",
      default: "h2"
    },
    {
      attribute: "classNames",
      type: "AccordionItemClassnames",
      description: "Allows to set custom class names for the accordion item slots.",
      default: "-"
    }
  ]}
/>

### Accordion Item Events

<APITable
  data={[
    {
      attribute: "onFocus",
      type: "(e: FocusEvent) => void",
      description: "Handler that is called when the element receives focus.",
      default: "-"
    },
    {
      attribute: "onBlur",
      type: "(e: FocusEvent) => void",
      description: "Handler that is called when the element loses focus.",
      default: "-"
    },
    {
      attribute: "onFocusChange",
      type: "(isFocused: boolean) => void",
      description: "Handler that is called when the element's focus status changes.",
      default: "-"
    },
    {
      attribute: "onKeyDown",
      type: "(e: KeyboardEvent) => void",
      description: "Handler that is called when a key is pressed.",
      default: "-"
    },
    {
      attribute: "onKeyUp",
      type: "(e: KeyboardEvent) => void",
      description: "Handler that is called when a key is released.",
      default: "-"
    },
    {
      attribute: "onPress",
      type: "(e: PressEvent) => void",
      description: "Handler called when the press is released over the target.",
      default: "-"
    },
    {
      attribute: "onPressStart",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press interaction starts.",
      default: "-"
    },
    {
      attribute: "onPressEnd",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press interaction ends, either over the target or when the pointer leaves the target.",
      default: "-"
    },
    {
      attribute: "onPressChange",
      type: "(isPressed: boolean) => void",
      description: "Handler called when the press state changes.",
      default: "-"
    },
    {
      attribute: "onPressUp",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press is released over the target, regardless of whether it started on the target or not.",
      default: "-"
    },
    {
      attribute: "onClick",
      type: "MouseEventHandler",
      description: "The native button click event handler (Deprecated) use onPress instead.",
      default: "-"
    }
  ]}
/>

---

### Types

#### Accordion Item Indicator Props

```ts
export type AccordionItemIndicatorProps = {
  /**
   * The current indicator, usually an arrow icon.
   */
  indicator?: ReactNode;
  /**
   * The current open status.
   */
  isOpen?: boolean;
  /**
   * The current disabled status.
   * @default false
   */
  isDisabled?: boolean;
};

type indicator?: ReactNode | ((props: AccordionItemIndicatorProps) => ReactNode) | null;
```

### Accordion Item classNames

```ts
export type AccordionItemClassnames = {
  base?: string;
  heading?: string;
  trigger?: string;
  titleWrapper?: string;
  title?: string;
  subtitle?: string;
  startContent?: string;
  indicator?: string;
  content?: string;
};
```

#### Motion Props

```ts
export type MotionProps = {
  /**
   * If `true`, the opacity of the content will be animated
   * @default true
   */
  animateOpacity?: boolean;
  /**
   * The height you want the content in its collapsed state.
   * @default 0
   */
  startingHeight?: number;
  /**
   * The height you want the content in its expanded state.
   * @default "auto"
   */
  endingHeight?: number | string;
  /**
   * The y-axis offset you want the content in its collapsed state.
   * @default 10
   */
  startingY?: number;
  /**
   * The y-axis offset you want the content in its expanded state.
   * @default 0
   */
  endingY?: number;
} & HTMLMotionProps;
```
